package cn.iocoder.yudao.module.biz.service.risk.riskInfo;

import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.biz.controller.admin.risk.controlMeasures.vo.BizControlMeasuresCreateReqVO;
import cn.iocoder.yudao.module.biz.controller.admin.risk.controlMeasures.vo.BizControlMeasuresRespVO;
import cn.iocoder.yudao.module.biz.controller.admin.risk.hazardResource.vo.BizHazardResourceCreateReqVO;
import cn.iocoder.yudao.module.biz.controller.admin.risk.hazardResource.vo.BizHazardResourceRespVO;
import cn.iocoder.yudao.module.biz.controller.admin.risk.riskInfo.vo.*;
import cn.iocoder.yudao.module.biz.convert.risk.controlMeasures.BizControlMeasuresConvert;
import cn.iocoder.yudao.module.biz.convert.risk.hazardResource.BizHazardResourceConvert;
import cn.iocoder.yudao.module.biz.convert.risk.riskInfo.BizRiskInfoConvert;
import cn.iocoder.yudao.module.biz.dal.dataobject.risk.controlMeasures.BizControlMeasuresDO;
import cn.iocoder.yudao.module.biz.dal.dataobject.risk.hazardResource.BizHazardResourceDO;
import cn.iocoder.yudao.module.biz.dal.dataobject.risk.riskInfo.BizRiskInfoDO;
import cn.iocoder.yudao.module.biz.dal.mysql.risk.riskInfo.RiskInfoMapper;
import cn.iocoder.yudao.module.biz.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.biz.service.risk.controlMeasures.BizControlMeasuresService;
import cn.iocoder.yudao.module.biz.service.risk.hazardResource.BizHazardResourceService;
import cn.iocoder.yudao.module.biz.utils.ExcelRisk;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.dept.DeptMapper;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import org.springframework.web.multipart.MultipartFile;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;

/**
 * 风险数据 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class RiskInfoServiceImpl implements RiskInfoService {

    @Resource
    private RiskInfoMapper infoMapper;

    @Resource
    private BizHazardResourceService hazardResourceService;

    @Resource
    private BizControlMeasuresService controlMeasuresService;

    @Resource
    private AdminUserMapper userMapper;

    @Resource
    private DeptMapper deptMapper;

    @Override
    public String createInfo(BizRiskInfoCreateReqVO createReqVO) {
        // 插入
        BizRiskInfoDO info = BizRiskInfoConvert.INSTANCE.convert(createReqVO);
        infoMapper.insert(info);
        // 返回
        return info.getId();
    }

    @Override
    public void updateInfo(BizRiskInfoUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateInfoExists(updateReqVO.getId());
        // 更新
        BizRiskInfoDO updateObj = BizRiskInfoConvert.INSTANCE.convert(updateReqVO);
        infoMapper.updateById(updateObj);
    }

    @Override
    public void deleteInfo(String id) {
        // 校验存在
        this.validateInfoExists(id);
        // 删除
        infoMapper.deleteById(id);
    }

    private void validateInfoExists(String id) {
        if (infoMapper.selectById(id) == null) {
            throw exception(ErrorCodeConstants.RISK_INFO_NOT_EXISTS);
        }
    }

    @Override
    public BizRiskInfoDO getInfo(String id) {
        return infoMapper.selectById(id);
    }

    @Override
    public List<BizRiskInfoDO> getInfoList(Collection<String> ids) {
        return infoMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<BizRiskInfoDO> getInfoPage(BizRiskInfoPageReqVO pageReqVO) {
        return infoMapper.selectPage(pageReqVO);
    }

    @Override
    public List<BizRiskInfoDO> getInfoList(BizRiskInfoExportReqVO exportReqVO) {
        return infoMapper.selectList(exportReqVO);
    }

    @Override
    public List<BizRiskInfoRespVO> getRiskInfoPage(BizRiskInfoPageReqVO pageReqVO) {
        Integer pageNo = pageReqVO.getPageNo();
        Integer pageSize = pageReqVO.getPageSize();
        //设置为limit开始的条数
        pageReqVO.setPageNo((pageNo - 1) * pageSize);
        pageReqVO.setCompanyId(SecurityFrameworkUtils.getLoginUser().getDeptId() + "");
        return infoMapper.getRiskInfoPage(pageReqVO);
    }

    @Override
    public Integer getRiskInfoCount(BizRiskInfoPageReqVO pageReqVO) {
        return infoMapper.getRiskInfoCount(pageReqVO);
    }

    @Override
    public List<BizRiskInfoExcelVO> getAllRiskInfo(BizRiskInfoExportReqVO pageReqVO) {
        return infoMapper.getAllRiskInfo(pageReqVO);
    }

    @Override
    public Long getRiskCount() {
        return infoMapper.selectCount(new QueryWrapperX<BizRiskInfoDO>().eqIfPresent("deleted", 0));
    }

    @Override
    public List<Map<String, Object>> getRiskPie() {
        BizRiskInfoPageReqVO pageReqVO = new BizRiskInfoPageReqVO();
        pageReqVO.setCompanyId(String.valueOf(SecurityFrameworkUtils.getLoginUser().getDeptId()));
        return infoMapper.getRiskPie(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class) // 添加事务，异常则回滚所有导入
    public RiskImportRespVO importExcel(MultipartFile file) {
        RiskImportRespVO riskImportRespVO = RiskImportRespVO.builder().createRisknames(new ArrayList<>())
                .failureRisknames(new LinkedHashMap<>()).build();
        try {
            Workbook wb = WorkbookFactory.create(file.getInputStream());
            //判断类型
            ExcelRisk excelRisk = new ExcelRisk();
            List<BizRiskInfoCreateReqVO> riskInfoCreateReqVOS = excelRisk.addReportByExcel(wb);
            Map<String,String> map = new HashMap<>();
            for(BizRiskInfoCreateReqVO riskInfoCreateReqVO : riskInfoCreateReqVOS){//遍历风险
                //风险点名称为空
                if(riskInfoCreateReqVO.getRiskPoint() == null || riskInfoCreateReqVO.getRiskPoint().equals("")){
                    map.put("","存在风险点为空的数据");
                    riskImportRespVO.setFailureRisknames(map);
                }else{//不为空
                    //判重
                    Long riskCount = infoMapper.selectCount(new QueryWrapperX<BizRiskInfoDO>().eqIfPresent("risk_point",riskInfoCreateReqVO.getRiskPoint())
                            .eqIfPresent("company_id",riskInfoCreateReqVO.getCompanyId())
                            .eqIfPresent("risk_type",riskInfoCreateReqVO.getRiskType()));
                    if(riskCount > 0){ //如果数据库中已有导入的风险点
                        map.put(riskInfoCreateReqVO.getRiskPoint(),"该风险点在数据库中已存在");
                        riskImportRespVO.setFailureRisknames(map);
                    }else{
                        //判断风险点的责任部门是否存在
                        DeptDO deptDO1 = deptMapper.selectOne(new QueryWrapperX<DeptDO>().eqIfPresent("name",riskInfoCreateReqVO.getResponsibleId()));
                        if(deptDO1 == null){//如果部门不存在
                            map.put(riskInfoCreateReqVO.getRiskPoint()+"的责任部门","不存在，请手动修改");
                            riskInfoCreateReqVO.setResponsibleId(null);
                            riskImportRespVO.setFailureRisknames(map);
                        }else{
                            riskInfoCreateReqVO.setResponsibleId(String.valueOf(deptDO1.getId()));
                        }
                        //判断责任人是否存在
                        if(riskInfoCreateReqVO.getDirectPersonName()!=null && !riskInfoCreateReqVO.getDirectPersonName().equals("")){
                            AdminUserDO userDO1 = userMapper.selectOne(new QueryWrapperX<AdminUserDO>().eqIfPresent("nickname",riskInfoCreateReqVO.getDirectPersonName()));
                            if(userDO1 == null){//如果责任人不存在
                                map.put(riskInfoCreateReqVO.getRiskPoint()+"的责任人","不存在，请手动修改");
                                riskInfoCreateReqVO.setDirectPersonId(null);
                                riskImportRespVO.setFailureRisknames(map);
                            }else{
                                riskInfoCreateReqVO.setDirectPersonId(userDO1.getId());
                            }
                        }
                        //风险点名称不为空，且数据库中没有重复
                        String riskId = createInfo(riskInfoCreateReqVO);
                        //遍历危险源
                        for(BizHazardResourceCreateReqVO hazardResourceCreateReqVO : riskInfoCreateReqVO.getHazardResourceCreateReqVOList()){
                            hazardResourceCreateReqVO.setRiskId(riskId);
                            //判断部门是否存在
                            DeptDO deptDO = deptMapper.selectOne(new QueryWrapperX<DeptDO>().eqIfPresent("name",hazardResourceCreateReqVO.getBusinessUnit()));
                            if(deptDO == null){//如果部门不存在
                                map.put(riskInfoCreateReqVO.getRiskPoint()+"的危险源的责任部门","不存在，请手动修改");
                                hazardResourceCreateReqVO.setBusinessUnit(null);
                                riskImportRespVO.setFailureRisknames(map);
                            }else{
                                hazardResourceCreateReqVO.setBusinessUnit(String.valueOf(deptDO.getId()));
                            }
                            if(hazardResourceCreateReqVO.getDutyPerson()!=null && !hazardResourceCreateReqVO.getDutyPerson().equals("")){
                                //判断责任人是否存在
                                AdminUserDO userDO = userMapper.selectOne(new QueryWrapperX<AdminUserDO>().eqIfPresent("nickname",hazardResourceCreateReqVO.getDutyPerson()));
                                if(userDO == null){//如果责任人不存在
                                    map.put(riskInfoCreateReqVO.getRiskPoint()+"的危险源的责任人","不存在，请手动修改");
                                    hazardResourceCreateReqVO.setPersonLiable(null);
                                    riskImportRespVO.setFailureRisknames(map);
                                }else{
                                    hazardResourceCreateReqVO.setPersonLiable(userDO.getId());
                                }
                            }
                            String hazardId = hazardResourceService.createHazardResource(hazardResourceCreateReqVO);
                            //遍历管控措施
                            for(BizControlMeasuresCreateReqVO controlMeasuresCreateReqVO : hazardResourceCreateReqVO.getControlMeasuresCreateReqVOList()){
                                controlMeasuresCreateReqVO.setHazardSourceId(hazardId);
                                controlMeasuresService.createControlMeasures(controlMeasuresCreateReqVO);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.out.println(e);
            Map<String,String> map = new HashMap<>();
            map.put("","更新失败");
            riskImportRespVO.setFailureRisknames(map);
        }
        return riskImportRespVO;
    }

    @Override
    public List<BizRiskInfoRespVO> getRiskInfoList(BizRiskInfoPageReqVO pageReqVO) {
        Integer pageNo = pageReqVO.getPageNo();
        Integer pageSize = pageReqVO.getPageSize();
        //设置为limit开始的条数
        pageReqVO.setPageNo((pageNo - 1) * pageSize);
        pageReqVO.setCompanyId(SecurityFrameworkUtils.getLoginUser().getDeptId() + "");
        List<BizRiskInfoRespVO> respVOS = infoMapper.getRiskInfoPage(pageReqVO);
        for(BizRiskInfoRespVO riskInfoRespVO : respVOS){//风险
            List<BizHazardResourceRespVO> hazardResourceRespVOList = hazardResourceService.getHazardResourceByRiskId(riskInfoRespVO.getId());
            for(BizHazardResourceRespVO hazardResourceRespVO : hazardResourceRespVOList){//危险源
                List<BizControlMeasuresRespVO> controlMeasuresRespVOList = controlMeasuresService.getControlMeasuresListByHazardId(hazardResourceRespVO.getId());
                hazardResourceRespVO.setControlMeasureList(controlMeasuresRespVOList);
            }
            riskInfoRespVO.setHazardSourceList(hazardResourceRespVOList);
        }
        return respVOS;
    }

    @Override
    public List<BizRiskInfoExcelVO> exportRiskInfoExcel(BizRiskInfoExcelVO exportReqVO) {
        exportReqVO.setCompanyId(SecurityFrameworkUtils.getLoginUser().getDeptId() + "");
        List<BizRiskInfoExcelVO> reList = infoMapper.exportRiskInfoExcel(exportReqVO);
        for(BizRiskInfoExcelVO vo2 : reList){
            if(vo2.getRiskType().equals("1")){
                vo2.setRiskTypeName("基础管理");
            }else if(vo2.getRiskType().equals("2")){
                vo2.setRiskTypeName("作业活动");
            }else if(vo2.getRiskType().equals("3")){
                vo2.setRiskTypeName("设备设施");
            }
        }
        return reList;
    }
}
